
// 导入 express 模块
var express = require('express');
const cors = require('cors');
// 引入 jsonwebtoken 模块
const jwt = require('jsonwebtoken');

// multer
const multer = require('multer')
const fs = require('fs')

var app = express();
app.use(express.static('wwwroot'));
// 允许所有源的跨域请求
app.use(cors());
app.use(express.json()); // 支持json

const secretKey = 'store_control'

// 判断文件夹是否存在
const folderPath = 'uploads';
fs.access(folderPath, fs.constants.F_OK, (err) => {
	if (err) {
	  // 文件夹不存在，创建文件夹
	  fs.mkdir(folderPath, { recursive: true }, (err) => {
		if (err) {
		  console.error('创建文件夹失败：', err);
		} else {
		  console.log('文件夹创建成功');
		}
	  });
	} else {
	  console.log('文件夹已存在');
	}
});

// 上传文件配置存储名称及存储文件
const storage = multer.diskStorage({
	destination: (req, file, cb) => {
	  cb(null, "uploads/"); // 第二个参数表示文件存放位置
	},
	filename: (req, file, cb) => {
	  const originalName = Buffer.from(file.originalname, "latin1").toString(
		"utf8"
	  );
	  console.log(originalName);
	  console.log("上传名称：" + originalName);
	  const newName = new Date().getTime() + "-" + originalName;
	  console.log("存储名称：" + newName);
	  cb(null, newName);
	},
});
// 上传文件
const upload = multer({ storage, limits: { fileSize: 1 * 1024 * 1024* 1024 } }).single('file');

// 导入 body-parser 模块
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));



// 导入db模块
var db = require('./db.js');
const { log } = require('console');
const json = require('body-parser/lib/types/json.js');

const { Entrepot, Admin, Detail,FileData, AuditDb } = db

// ---------------------------------------------------------------------------------
// app.post('/aaa', (req, res) => {
// 	console.log(req.body);
// 	res.send('111111')
// })
// 添加管理员
app.post('/api/admin/add', async (req, res) => {


	try {
		const data = tokenVerify(req, res) // 验证token
		console.log(data);
		if (!data) return
		// 有条件查询
		const adminList = await Admin.find({ adminname: req.body.adminname })
		if (adminList.length == 0) {
			// 没有
			var admin = new Admin({
				adminname: req.body.adminname,
				password: req.body.password,
				role: req.body.role,
				asrole:req.body.asrole
			});
			const result = await admin.save();
			if (result) {
				res.send({
					message: '添加管理员成功'
				})
			} else {
				res.send({
					message: '添加管理员失败，请重新添加'
				})
			}
		} else {
			// 有
			return res.status(400).json({ message: '用户名已存在' });
		}
	}
	catch (err) {

		res.send(err)
	}

})

// 管理员登录
app.post('/api/admin/login', async (req, res) => {

	// console.log(1111111, req);
	console.log('`````````````````');
	try {
		// 有条件查询
		const admin = await Admin.findOne({ adminname: req.body.adminname })

		// res.send(admin)
		if (admin) {
			// 用户存在
			if (admin.password == req.body.password) {
				const { adminname, password, role, asrole } = admin;
				res.status(200).json({
					message: '登录成功',
					adminname:req.body.adminname,
					role:role,
					asrole:asrole,
					token: jwt.sign({
						adminname, password, role
					}, secretKey, { expiresIn: '1y' })
				})
			} else {
				res.status(400).json({ message: '密码错误' });
			}
		} else {
			// 不存在
			res.status(400).json({ message: '用户名不存在' });
		}

	}
	catch (err) {

		res.send(err)
	}

})

// 管理员列表
app.post('/api/admin/list', async (req, res) => {


	try {
		const data = tokenVerify(req, res) // 验证token
		if (!data) return

		// 查询
		const adminList = await Admin.find({})
		// res.send(admin)
		// console.log(adminList);
		res.status(200).json(adminList)
	}
	catch (err) {
		res.send(err)
	}

})

// 管理员删除
app.post('/api/admin/delete', async (req, res) => {


	try {
		const data = tokenVerify(req, res) // 验证token
		if (!data) return

		const { _id } = req.body;

		const result = await Admin.findByIdAndRemove(_id);

		if (!result) {
			return res.status(404).json({ message: '管理员不存在' });
		}

		res.status(200).json({ message: '删除管理员成功' });
	} catch (error) {
		res.status(500).json({ message: '删除管理员失败' });
	}

})

// 管理员修改
app.post('/api/admin/update', async (req, res) => {


	try {
		const data = tokenVerify(req, res) // 验证token
		if (!data) return

		const { adminname, password, role,_id,asrole } = req.body;
		// const { newData } = req.body;

		delete req.body.adminname;

		const updatedData = await Admin.findByIdAndUpdate(_id,{adminname, password, role,asrole}, req.body, { new: true });
		if (!updatedData) {
			return res.status(404).json({ message: '数据不存在' });
		}

		res.status(200).json({ message: '数据更新成功', data: updatedData });
	} catch (error) {
		// console.error(error);
		res.status(500).json({ message: '数据更新失败' });
	}
});

// 管理员信息
app.post('/api/admin/info', async (req, res) => {


	try {
		const data = tokenVerify(req, res) // 验证token
		if (!data) return

		const { _id } = req.body;

		const admin = await Admin.findOne({ _id });

		if (!admin) {
			return res.status(404).json({ message: '管理员不存在' });
		}

		res.status(200).json(admin);
	} catch (error) {
		console.error(error);
		res.status(500).json({ message: '获取管理员信息失败' });
	}
});



// 查库存列表
app.post('/api/data/list', async (req, res) => {


	try {
		const data = tokenVerify(req, res) // 验证token
		if (!data) return

		// 查询
		const dataList = await Entrepot.find({})
		res.status(200).json(dataList)
	}
	catch (err) {
		res.send(err)
	}
});

// 搜索
app.post('/api/data/search', async (req, res) => {
  try {
    const data = tokenVerify(req, res) // 验证token
    if (!data) return

    // 获取搜索参数
    const { liaohao } = req.body
    if (!liaohao) {
      res.status(400).send('缺少搜索参数')
      return
    }

    // 查询
    const dataList = await Entrepot.find({ liaohao: { $regex: liaohao, $options: 'i' } })
    res.status(200).json(dataList)
  } catch (err) {
    res.send(err)
  }
})

// 添加数据
app.post('/api/data/add', async (req, res) => {


	try {
		const data = tokenVerify(req, res) // 验证token
		if (!data) return
		var entrepot = new Entrepot(req.body);
		const result = await entrepot.save();

		const detail = new Detail({
			...req.body,
			time: new Date().getTime(),
			type: 1, // 1 存 2 取
			adminname: data.adminname,
			num: null
		});
		const detailResult = await detail.save();

		if (result && detailResult) {
			res.send({
				message: '添加成功'
			})
		} else {
			res.send({
				message: '添加管理员失败，请重新添加'
			})
		}
	}
	catch (err) {
		res.send(err)
	}
});
// 删除数据
app.post('/api/data/delete', async (req, res) => {


	try {
		const data = tokenVerify(req, res) // 验证token
		if (!data) return

		const { _id } = req.body;

		const result = await Entrepot.findByIdAndRemove(_id);

		if (!result) {
			return res.status(404).json({ message: '数据不存在' });
		}

		res.status(200).json({ message: '删除成功' });
	} catch (error) {
		res.status(500).json({ message: '删除失败' });
	}
});
// 取货
app.post('/api/data/update', async (req, res) => {
	try {
		const data = tokenVerify(req, res) // 验证token
		if (!data) return
		const { num, _id } = req.body;
		const findItem = await Entrepot.findById(_id)
		if (!findItem) return res.status(404).json({ message: '数据不存在' });
		if (!+num) return res.status(404).json({ message: '请输入要取的数量' });
		if (+num > +findItem.kucun || +findItem.kucun == 0) return res.status(404).json({ message: '库存不足' });
		const updatedData = await Entrepot.findByIdAndUpdate(_id, { kucun: findItem.kucun - (+num) }, { new: true });

		delete findItem._doc._id
		delete findItem._doc.id
		const detail = new Detail({
			...findItem._doc,
			kucun: findItem.kucun - (+num),
			time: new Date().getTime(),
			type: 2, // 1 存 2 取
			adminname: data.adminname,
			num
		});
		await detail.save();

		res.status(200).json({ message: '数据更新成功', data: updatedData });
	} catch (error) {
		// console.error(error);
		res.status(500).json({ message: '数据更新失败' });
	}
});
// -----------------------------------

// 编辑
app.post('/api/data/updateKucun', async (req, res) => {
  try {
    const data = tokenVerify(req, res); // 验证token
    if (!data) return;
    const _id = req.body._id;
    if (!_id) {
      res.status(400).send('缺少ID参数');
      return;
    }
    const kucun = req.body.kucun;
    if (!kucun) {
      res.status(400).send('缺少数量参数');
      return;
    }
    // 使用前端传递的kucun值作为Detail文档中的num字段

		const record = await Entrepot.findOne({_id})
    // 更新库存数量
    const updateResult = await Entrepot.findByIdAndUpdate(_id, { kucun: kucun}, { new: true });
    if (!updateResult) {
      res.status(404).send('未找到要修改的库存');
      return;
    }
		const detail = {
			...updateResult.toObject(),
			time: new Date().getTime(),
			type: 1, // 1 存 2 取
			adminname: data.adminname,
			num:+kucun - +record.kucun, // 保存变动的库存量
		};
		delete detail._id;
		delete detail.id;
		const detailRes = await new Detail(detail).save();
    if (!detailRes) {
      res.status(500).send("库存详情创建失败");
      return;
    }

    res.status(200).json({ updateResult, detailRes });
  } catch (err) {
    res.send(err);
  }
});




// 存取列表
app.post('/api/data/detailList', async (req, res) => {


	try {
		const data = tokenVerify(req, res) // 验证token
		if (!data) return

		// 查询
		const dataList = await Detail.find({})
		res.status(200).json(dataList)
	}
	catch (err) {
		res.send(err)
	}
});

// 删除存取列表
app.post('/api/data/detailList/delete', async (req, res) => {
  try {
    const data = tokenVerify(req, res) // 验证token
    if (!data) return

    const detailId = req.body._id // 获取要删除的详情id
    if (!detailId) {
      res.status(400).send('缺少id参数')
      return
    }

    const deleted = await Detail.findByIdAndDelete(detailId)
    if (!deleted) {
      res.status(404).send('未找到要删除的详情')
      return
    }

    res.status(200).send('删除成功')
  } catch (err) {
    res.send(err)
  }
})

// 上传文件
const requireLogin = (req, res, next)=>{
	const data = tokenVerify(req, res) // 验证token
	if (!data) return
	next()
}
app.post("/api/upload", requireLogin, async (req, res) => {
	try {
		upload(req, res, async (err)=>{
			if (err instanceof multer.MulterError) {
				// Multer 相关错误
				if (err.code === 'LIMIT_FILE_SIZE') {
				return res.status(400).json({ message: '上传文件大小超过限制' });
				}
				// 其他 Multer 错误处理
				return res.status(500).json({ message: '文件上传失败' });
			} else if (err) {
				// 其他错误处理
				return res.status(500).json({ message: '文件上传失败' });
			}
			const data = tokenVerify(req, res)
			const fileData = new FileData({
				name: req.file.filename,
				time: new Date().getTime(),
				type: 1, // 1 存 2 下载 3 文件已被删除
				adminname: data.adminname,
				status: 0 // 1 已审核 0 未审核
			});
			addAudit(data.adminname, 'add', fileData._id)
			await fileData.save();
			// 文件上传成功
			res.json({ message: '文件上传成功' });
		});
	} catch (err) {
		res.send(err)
	}
});
// 获取可下载列表
app.post('/api/downList', async (req, res) => {
	try {
		const data = tokenVerify(req, res) // 验证token
		if (!data) return

		// const newVar = await AuditDb.find({  status: 1, operation: 'add'}).populate('targetId');

		// const filedata = await FileData.find({ type: 1, status: 1 })

		// const files = await FileData.find();
		// const fileIds = files.map(file => file._id);
		// const fileStatuses = await AuditDb.find({ targetId: { $in: fileIds }, status: 1, operationType: 'add' });
		//
		// const fileList = files.filter(file => {
		// 	const status = fileStatuses.find(status => status.targetId === file._id.toString());
		// 	return status !== undefined && status.status === 1;
		// });

		// res.json(fileList);



		const fileList = await FileData.aggregate([
			{
				$lookup: {
					from: 'auditdbs',
					localField: '_id',
					foreignField: 'targetId',
					as: 'auditData',
				},
			},
			{
				$match: {
					'auditData.status': 1,
					'auditData.operationType': 'add',
					'type': { $ne: 3 }
				},
			},
			{
				$project: {
					_id: 1,
					name: 1,
					time: 1,
					type: 1,
					adminname: 1,
				},
			},
		]);
		res.status(200).json(fileList)
	} catch (err) {
		//res.send(err)
		console.log(err)
		res.status(200).json([]);
	}
})
// 返回下载地址
app.post('/api/download', async (req, res) => {
	try {
		const data = tokenVerify(req, res) // 验证token
		if (!data) return

		const { _id } = req.body;


		const querys = await AuditDb.find({ targetId: _id, operationType: 'upload', userName: data.adminname });
		if (querys.length > 0){
			if (querys[0].status === -1) {
				res.status(200).json({ message: '审核中' });
			}
			if (querys[0].status === 0) {
				res.status(200).json({ message: '审核不通过' });
			}
			if (querys[0].status === 1) {
				const result = await FileData.findOne({ _id });
				if (!result) {
					return res.status(404).json({ message: '数据不存在' });
				}
				const fileData = new FileData({
					name: result.name,
					time: new Date().getTime(),
					type: 2, // 1 存 2 下载 3 文件已被删除
					adminname: data.adminname
				});
				await fileData.save();
				const downloadUrl = req.protocol + '://' + req.get('host') + '/download/' + result.name;
				res.json({ message: '成功',data: downloadUrl });
			}
		}else {
			addAudit(data.adminname, 'upload', _id)
			res.status(200).json({ message: '已提交审核' });
		}
	} catch (err) {
		res.send(err)
	}
})
// 定义文件下载的路由
app.get('/download/:filename', (req, res) => {
	const filename = req.params.filename;
	const filePath = 'uploads/' + filename;
	res.download(filePath);
});

// 删除文件
app.post('/api/deleteFile', async (req, res) => {
	try {
		const data = tokenVerify(req, res) // 验证token
		if (!data) return
		const { _id } = req.body;
		const querys = await AuditDb.find({ targetId: _id, operationType: 'del', userName: data.adminname });
		if (querys.length > 0){
			if (querys[0].status === -1) {
				res.status(200).json({ message: '审核中' });
			}
			if (querys[0].status === 0) {
				res.status(200).json({ message: '审核不通过' });
			}
		}else {
			addAudit(data.adminname, 'del', _id)
			res.status(200).json({ message: '已提交审核' });
		}
		// const result = await FileData.findByIdAndRemove(_id); // 真删
		// const result = await FileData.findByIdAndUpdate(_id, { type: 3 }, { new: true }) // 改状态假删
		// if (!result) {
		// 	return res.status(404).json({ message: '数据不存在' });
		// }
		// console.log('====================================');
		// console.log('uploads/'+result.name);
		// console.log('====================================');
		// fs.unlink('uploads/'+result.name,(err)=>{
		// 	if(err){
		// 		res.status(500).json({ message: '删除失败' });
		// 	}
		// 	res.status(200).json({ message: '删除成功' });
		// })
	} catch (error) {
		console.log('====================================');
		console.log(error);
		console.log('====================================');
		res.status(500).json({ message: '删除失败' });
	}

})

// ---------------------------------------------------------------------------------

// 审核列表
app.post('/api/audit/list', async (req, res) => {


	try {
		const data = tokenVerify(req, res) // 验证token
		if (!data) return

		// 查询
		const auditList = await AuditDb.find()
		res.status(200).json(auditList)
	}
	catch (err) {
		res.send(err)
	}
});

// 修改审核状态
app.post('/api/audit/updateStatus', async (req, res) => {


	try {
		const data = tokenVerify(req, res) // 验证token
		if (!data) return

		const { _id } = req.body;
		// 查询
		const resultAuditDb = await AuditDb.findByIdAndUpdate(_id, { status: req.body.status})
		if (req.body.status === 1 && resultAuditDb.operationType === 'del'){
			const result = await FileData.findByIdAndUpdate(resultAuditDb.targetId, { type: 3 }, { new: true }) // 改状态假删
			if (!result) {
				return res.status(404).json({ message: '数据不存在' });
			}
			console.log('====================================');
			console.log('uploads/'+result.name);
			console.log('====================================');
			fs.unlink('uploads/'+result.name,(err)=>{
				if(err){
					return res.status(500).json({ message: '删除失败' });
				}
				return res.status(200).json({ message: '删除成功' });
			})
			if (!result) {
				return res.status(404).json({ message: '数据不存在' });
			}
		}
		return res.status(200).json({ message: '审核成功' });
	}
	catch (err) {
		console.log(err)
		res.send(err)
	}
});

// 添加审核
const addAudit = (userName, type, targetId) => {

	const auditDbModel = new AuditDb({
		userName: userName,
		operationType: type, // 操作类型  add del update upload
		targetId: targetId,  // 目标名称
		status: -1  // 审核状态  1 通过  0 未通过 -1 未审核
	})
	auditDbModel.save()
}


const tokenVerify = (req, res) => {
	try {
		const decoded = jwt.verify(req.headers.authorization, secretKey);
		return decoded;
	} catch (error) {
		res.json({
			message: '请先登陆',
			code: 403
		})
		return false
	}
}

// 监听端口是 3000
app.listen(3000, function () {
	console.log('running...');
})
